/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

class Bitops {

    public static double RunBitOp1() {
        int res = 0;
        int[] resources = new int[]{12, 43, 56, 76, 89, 54, 45, 32, 35, 47, 46, 44, 21, 37, 84};
        double start = System.nanoTime();
        int resourcesLength = resources.length - 1;
        for (int i = 0; i < 6000000; i++) {
            int bi3b = 0xE994;
            int b = resources[(i & res) & resourcesLength];
            res += 3 & (bi3b >> ((b << 1) & 14));
            res += 3 & (bi3b >> ((b >> 2) & 14));
            res += 3 & (bi3b >> ((b >> 5) & 6));
        }
        double end = System.nanoTime();
        System.out.println(""+res);
        double time = (end - start) / 1000000;
        System.out.println("Numerical Calculation - RunBitOp1:\t"+ time +"\tms");
        return time;
    }

    public static double RunBitOp2() {
        int res = 0;
        double start = System.nanoTime();
        for (int i = 0; i < 6000000; i++) {
            int b = i;
            int m = 1;
            int c = 0;
            while (m < 0x100) {
                if ((b & m) != 0) {
                    c += 1;
                }
                m <<= 1;
            }
            res += c;
        }
        double end = System.nanoTime();
        System.out.println(""+res);
        double time = (end - start) / 1000000;
        System.out.println("Numerical Calculation - RunBitOp2:\t"+ time +"\tms");
        return time;
    }

    public static double RunBitOp3() {
        int res = 0;
        double start = System.nanoTime();
        for (int y = 0; y < 6000000; y++) {
            int x = y;
            int r = 0;
            while (x != 0) {
                x &= x - 1;
                ++r;
            }
            res += r;
        }
        double end = System.nanoTime();
        System.out.println(""+res);
        double time = (end - start) / 1000000;
        System.out.println("Numerical Calculation - RunBitOp3:\t"+ time +"\tms");
        return time;
    }


    public static double RunBitOp4() {
        int[] results = new int[]{3, 53, 76, 37, 82, 23, 66, 17, 82, 43, 77, 93, 28, 24, 8};
        int[] resources = new int[]{12, 43, 56, 76, 89, 54, 45, 32, 35, 47, 46, 44, 21, 37, 84};
        int res = 0;
        double start = System.nanoTime();
        int resultsLength = results.length - 1;
        int resourcesLength = resources.length - 1;
        for (int i = 0; i < 6000000; i++) {
            res |= ~(1 << (resources[i & resourcesLength] ^ 31));
        }
        double end = System.nanoTime();
        System.out.println(""+res);
        double time = (end - start) / 1000000;
        System.out.println("Numerical Calculation - RunBitOp4:\t"+ time +"\tms");
        return time;
    }


    public static void BitopsRun() {
        RunBitOp1();
        RunBitOp2();
        RunBitOp3();
        RunBitOp4();
    }
}

class Benchmark {
    public static void main(String[] args) {
        Bitops.BitopsRun();
    }
}